package com.util.reflex;



import javax.servlet.http.HttpServletRequest;
import javax.swing.plaf.synth.SynthDesktopIconUI;
import java.lang.reflect.*;

import static java.lang.Math.E;
import static javafx.scene.input.KeyCode.*;

/**
 * 反射的测试
 * 代码参考：https://blog.csdn.net/huangliniqng/article/details/88554510
 */
public class FanShe {


    /**
     * 获取构造器
     */
    public static void studentGirl(){
        StudentGirl girl = new StudentGirl();
        Class clazz = girl.getClass();
        Constructor[] constructors = clazz.getDeclaredConstructors(); //获取所有构造方法
        for(int i=0;i<constructors.length;i++){
            System.out.println(String.format("学生妹的构造器：%s",constructors[i]));
            System.out.println("修饰符:"+Modifier.toString(constructors[i].getModifiers())); //获取修饰符
            Class[] paramter = constructors[i].getParameterTypes(); //获取参数数组
            for(int j = 0;j<paramter.length;j++){
                System.out.println("参数类型："+paramter[j].getName()); //获取参数类型
            }

        }

        try {
            Constructor constructor = clazz.getDeclaredConstructor(); //获取无参构造器
            System.out.println("获取无参构造器:"+constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }


    }
    /**
     * 基本反射语法
     * 获取Class对象
     */
    public static void baseFanShe(){
          String name = "我要日死你";
          Class c1 = name.getClass(); //获取class对象
          System.out.println(c1.getName()); //获取类的完整路径名
          System.out.println(c1);

          /*------TYPE属性----*/
          Class c2  = Boolean.TYPE;
          Class c3 = Byte.TYPE;
          Class c4 = Float.TYPE;
          Class c5 = Double.TYPE;
          System.out.println(String.format("c2:%s c3:%s c4:%s c5:%s",c2,c3.getName(),c4.getName(),c5.getSimpleName()));

      }

    /**
     * 调用指定构造器
     * @throws Exception
     */
      public static void gouzao() throws Exception {
          /*=====公有构造器=========*/

        Class[]  p; //构造参数数组
          p = new Class[]{String.class,int.class};
        StudentGirl girl = new StudentGirl();
        Class clazz = girl.getClass();
        Constructor constructor;
        constructor = clazz.getDeclaredConstructor(p); //获取指定构造器
        constructor.newInstance("大咪咪",18); //new构造器
          /*====私有构造器=====*/

          p = new Class[]{int.class};
          constructor = clazz .getDeclaredConstructor(p);
          constructor.setAccessible(true); // 取消语言检查
          constructor.newInstance(16);
      }

    /**
     * 调用 方法
     */
    public  static void fangfa() throws Exception{
        /*=====运用反射获取私有访求======*/
        System.out.println(
                "反射调用方法"
        );
          StudentGirl girl = new StudentGirl();
          Class c = girl.getClass();
          Class[] param; //构造参数组
          param = new Class[]{String.class,Integer.class,Boolean.class};
          Method method = c.getDeclaredMethod("yuepao",param);
          method.setAccessible(true);

          method.invoke(girl,"荡妇",null,null); //运行方法
        String name = "粉木耳";
        int barth = 15;
        boolean flag = true;
        Object[] p = new Object[3];
        p[0] = name;
        p[1] =barth;
        p[2]  = flag;
         method.invoke(girl,p);
        System.out.println("调用方法结束");


          /*======设置成员变量========*/
        Field field = c.getDeclaredField("name"); //获取成员变量
        Field age = c.getDeclaredField("age");
          field.setAccessible(true);
          field.set(girl,"淫娃");
          age.setAccessible(true);
          age.set(girl,16);
        System.out.println(String.format("我认识一个%s,今年只有%s岁,真的好爽",field.get(girl),age.get(girl)));

      }
      public static void fuckGirl() {
        SheJing sheJing = new SheJing();
        Class c = sheJing.getClass();
          Method method = null;
          try {
              Method[]  fuck = c.getMethods();
              for(Method m:fuck){
                //  System.out.println(m);
                  if("fuck".equals(m.getName())){
                      method = m;
                  }
              }

          } catch (Exception e) {
              e.printStackTrace();
          }
            //封闭请求参数
          try {
              //获取参数的class对象
              Class[] parameters = method.getParameterTypes();
              for(Class p:parameters){
                  System.out.println("参数的class对象:"+p);
                  Field[] field = p.getDeclaredFields();
                  for(Field f:field){
                      System.out.println("参数成员:"+f.getName());
                  }
              }
              System.out.println("方法的返回对象："+method.getReturnType());
            Parameter[] p2 =   method.getParameters();

            for(Parameter p3:p2){
                System.out.println("方法参数名:"+p3);
//                System.out.println("方法参数名:"+p3.getName());
                System.out.println("方法参数名类型:"+ p3.getParameterizedType());
                System.out.println("方法参数名类型2:"+p3.getType().getName().toString());
                System.out.println(String.format("参数类型比较：String:%s",p3.getType().equals(String.class)));
                System.out.println("方法参数名类型3:");
              Type type =   p3.getParameterizedType();



            }
              System.out.println(String.format("获取参数个数:%s",method.getParameterCount()));
            //封闭的方法有缺陷，后期再改吧

          } catch (Exception e) {
              e.printStackTrace();
          }

      }

    /**
     *反射参数
     */
    public static <T> T fObject(HttpServletRequest request) throws Exception{
        SheJing sheJing = new SheJing();
        Class c = sheJing.getClass();
        Method[] methods = c.getMethods();

        //获取方法
        Method method = null;
        for(Method m : methods){
            if("fuck".equals(m.getName())){
                method = m;
            }
        }
        method.setAccessible(true);
        //获取参数class对象
        Class clazz = method.getParameterTypes()[0];
        //获取对象成员
        Field[] fields = clazz.getDeclaredFields();
        //设置成员变量的值

        for(Field f:fields){
            f.set(f.getName(),(Object) request.getHeader(f.getName()));
        }

        return (T) clazz.newInstance();


      }
      public static void panType(){
        StudentGirl girl = new StudentGirl();
       Class c =  girl.getClass();
       Class bool = Boolean.TYPE;
          System.out.println("实体与基本类型比较");
          System.out.println(c.equals(bool));
      }
      public static Method getMethod(Class c ,String way){

          Method[] methods = c.getMethods();

          //获取方法
          Method method = null;
          for(Method m : methods){
              if(way.equals(m.getName())){
                  method = m;
              }
          }
          if(method==null){
              throw new RuntimeException(String.format("没有获取到%s方法",way));
          }
          return  method;
      }
      public static void deper() throws Exception{
            Class c  = Class.forName("com.util.reflex.SheJing");
          StudentGirl girl = new StudentGirl("小娘子",16);
          Object[] o  = new Object[]{girl};

        Method method = getMethod(c,"deper");

        method.invoke(c.newInstance(),o);
      }
    public static void main(String[] args) throws Exception{
        StudentGirl girl  = new StudentGirl();
        Class clazz = girl.getClass();
        System.out.println(String.format("%s--%s",clazz.getName(),clazz.getSimpleName()));
        baseFanShe();
        studentGirl();
        gouzao();
        fangfa();
        fuckGirl();
        panType();
        deper();
    }
}
